/*
 * Copyright 2006-2007 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package asphalt2.container
{
	import asphalt2.event.PageContainerEvent;
	import asphalt2.util.UIUtil;
	
	import flash.display.DisplayObject;
	import flash.events.Event;
	
	import mx.containers.ViewStack;
	import mx.core.ClassFactory;
	import mx.core.Container;
	import mx.effects.Effect;
	import mx.effects.Fade;
	import mx.events.EffectEvent;
	import mx.events.FlexEvent;
	/**
	 * ページ表示用コンテナクラス
	 * PageContainerEventをディスパッチすると、このコンテナクラスが受取り、
	 *　画面を切り替えます。
	 * @author c9katayama
	 **/	
	public class PageContainer extends ViewStack
	{
		/** ページが消えるときにエフェクト */
		private var _pageOutEffect:Effect;
		/** ページが表示されるときにエフェクト */
		private var _pageInEffect:Effect;
		/** 処理中のPageContainerEvent */
		private var processingEventObject:PageContainerEvent;
		/** historyManager利用時、スタックしておくViewの数*/
		private var _historyStackNum:int = 1;
		/**イベントをリッスンする対象ルートオブジェクト*/
		protected var listenRoot:DisplayObject;
		
		public function set pageOutEffect(effect:Effect):void{
			_pageOutEffect = effect;	
		}
		public function get pageOutEffect():Effect{
			return _pageOutEffect;
		}
		public function set pageInEffect(effect:Effect):void{
			_pageInEffect = effect;	
		}
		public function get pageInEffect():Effect{
			return _pageInEffect;
		}
		public function set historyStackNum(num:int):void{
			this._historyStackNum = num;
		}
		public function get historyStackNum():int{
			return _historyStackNum;
		}
				
		public function PageContainer(){
			super();
			UIUtil.addOnceEventListener(this,FlexEvent.CREATION_COMPLETE,function(e):void{
				setup();
			});
			setDefaultEffect();
		}
		protected function setDefaultEffect():void{
			//デフォルトのエフェクト
			var defaultPageOut:Fade = new Fade();
			defaultPageOut.alphaFrom = 1;
			defaultPageOut.alphaTo = 0;
			defaultPageOut.duration=400;
			this.pageOutEffect = defaultPageOut;
			var defaultPageIn:Fade = new Fade();
			defaultPageIn.alphaFrom = 0;
			defaultPageIn.alphaTo = 1;
			defaultPageIn.duration=400;
			this.pageInEffect = defaultPageIn;
		}
		protected function setup():void{
			this.listenRoot = UIUtil.findRoot();
			listenRoot.addEventListener(PageContainerEvent.NEXTPAGE,handleNextPage);
			listenRoot.addEventListener(Event.REMOVED,handleRemove);
			pageOutEffect.addEventListener(EffectEvent.EFFECT_END,handlePageOutEffectEnd);
			pageInEffect.addEventListener(EffectEvent.EFFECT_END,handlePageInEffectEnd);
		}
		
		protected function handleNextPage(e:PageContainerEvent):void{
			if(this.id == e.targetId){
				if(!pageOutEffect.isPlaying && !pageInEffect.isPlaying){
					this.processingEventObject = e;
					pageOutEffect.play([this.getChildAt(this.selectedIndex)]);
				}
			}
		}
		protected function handlePageOutEffectEnd(e:EffectEvent):void{
			var factory:ClassFactory = new ClassFactory(processingEventObject.nextPage);
			factory.properties = processingEventObject.nextPageProperties;			
			var comp:Container = factory.newInstance() as Container;
			if(!historyManagementEnabled){
				this.removeAllChildren();
			}
			this.addChild(comp);
			if(historyManagementEnabled){
				this.selectedIndex = this.getChildren().length-1;
			}
			processingEventObject = null;

			UIUtil.addOnceEventListener(comp,FlexEvent.CREATION_COMPLETE,function(e):void{
				pageInEffect.play([comp]);
			});
		}
		protected function handlePageInEffectEnd(e:EffectEvent):void{
			if(historyManagementEnabled){
				//一定数以上は破棄
				if(getChildren().length>=historyStackNum){
					removeChildAt(0);
				}
			}
		}
		protected function handleRemove(e:Event):void{
			if(UIUtil.isParentOrThis(this,DisplayObject(e.target))){
				trace("dispose"+this);
				dispose();
			}			
		}
		protected function dispose():void{
			this.removeAllChildren();
			listenRoot.removeEventListener(PageContainerEvent.NEXTPAGE,handleNextPage);
			listenRoot.removeEventListener(Event.REMOVED,handleRemove);
			listenRoot = null;
			_pageOutEffect = null;
			_pageInEffect = null;
			processingEventObject = null;			
		}
	}
}